﻿// Copyright 2007 Arnoud de Vries
// 
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
// 
//     http://www.apache.org/licenses/LICENSE-2.0
// 
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

#include "service.h"
#include "parser.cpp.h"


/*---------------------------------------------------------
  Globals
---------------------------------------------------------*/
const wchar_t*  g_languageName              = L"NVelocity";
const wchar_t*  g_languageFileExtensions[]  = { L".vm",  NULL };
const CLSID     g_languageCLSID             = {0xDFDE06E4, 0xFBBC, 0x4D71, { 0xAB, 0x6A, 0x11, 0x9F, 0xF4, 0x5C, 0xFD, 0x82 }};

const LanguageProperty g_languageProperties[] =
{
  { L"RequestStockColors", 0 },

  { L"ShowCompletion",     1     },
  { L"SortMemberList",     1     },

  { L"CodeSense",          0  },
  { L"CodeSenseDelay",     1500 },
  { L"MaxErrorMessages",   5     },
  { L"QuickInfo",          1     },
  { L"MatchBraces",        1     },
  { L"ShowMatchingBrace",  1     },
  { L"MatchBracesAtCaret", 1     },

  { NULL, 0 }
};

/*---------------------------------------------------------
  Create Service
---------------------------------------------------------*/
HRESULT CreateBabelService( out IBabelService** babelService )
{
  TRACE(L"CreateBabelService");
  OUTARG(babelService);

  *babelService = new Service();
  if (*babelService == NULL) return E_OUTOFMEMORY;

  return S_OK;
}

override const CommentFormat *Service::getCommentFormat() const
{
    static CommentFormat commentFormat =  { "##", "#*", "*#", false  };
    return &commentFormat;
}


/*---------------------------------------------------------
  Tokens
---------------------------------------------------------*/
override const TokenInfo* Service::getTokenInfo() const
{
  static TokenInfo tokenInfoTable[] =
  {
	    // NOTE: The following token definition was generated by the wizard according with
    // the information you provided. However it is possible that this code will not work
    // if there is a missmatch between the char class defined for some tokens and what is
    // expected by the lexer.
{ IDENTIFIER, ClassIdentifier, "identifier '%s", CharIdentifier },
{ NUMBER, ClassNumber, "", CharDefault },
{ KWIF, ClassKeyword, "", CharKeyword },
{ KWELSE, ClassKeyword, "", CharKeyword },
{ KWWHILE, ClassKeyword, "", CharKeyword },
{ KWFOR, ClassKeyword, "", CharKeyword },
{ KWEND, ClassKeyword, "", CharKeyword},
{ KWSTOP, ClassKeyword, "", CharKeyword},
{ KWMACRO, ClassKeyword, "", CharKeyword},
{ KWSET, ClassKeyword, "", CharKeyword},
{ KWLITERAL, ClassKeyword, "", CharKeyword},
{ KWIN, ClassKeyword, "", CharKeyword},
{ KWINCLUDE, ClassKeyword, "", CharKeyword},
{ KWPARSE, ClassKeyword, "", CharKeyword},
{ KWBEFORE, ClassKeyword, "", CharKeyword},
{ KWAFTER, ClassKeyword, "", CharKeyword},
{ KWBETWEEN, ClassKeyword, "", CharKeyword},
{ KWODD, ClassKeyword, "", CharKeyword},
{ KWBEFOREALL, ClassKeyword, "", CharKeyword},
{ KWAFTERALL, ClassKeyword, "", CharKeyword},
{ KWCAPTUREFOR, ClassKeyword, "", CharKeyword},
{ KWBLOCKCOMPONENT, ClassKeyword, "", CharKeyword},
{ KWCOMPONENT, ClassKeyword, "", CharKeyword},
{ KWPARSE, ClassKeyword, "", CharKeyword},
{ KWEACH, ClassKeyword, "", CharKeyword},

{ LINE_COMMENT, ClassComment, "", CharLineComment },
{ STRING, ClassString, "", CharString },

{ ',', ClassText, "','" , CharDelimiter, TriggerParamNext },     
{ ';', ClassDefault, "", CharDefault },
{ '(', ClassText, "'('", CharDelimiter, TriggerParamStart | TriggerMatchBraces },
{ ')', ClassText, "')'", CharDelimiter, TriggerParamEnd | TriggerMatchBraces }, 
{ '{', ClassDefault, "", CharDelimiter },
{ '}', ClassDefault, "", CharDelimiter },
{ '[', ClassText, "'['", CharDelimiter , TriggerParamStart | TriggerMatchBraces },
{ ']', ClassText, "']'", CharDelimiter , TriggerParamStart | TriggerMatchBraces },
{ '=', ClassDefault, "=", CharDelimiter },
{ '+', ClassDefault, "+", CharDelimiter },
{ '-', ClassDefault, "-", CharDelimiter },
{ '*', ClassDefault, "*", CharDelimiter },
{ '/', ClassDefault, "/", CharDelimiter },
{ '!', ClassDefault, "!", CharDelimiter },
{ '&', ClassDefault, "&", CharDelimiter },
{ '|', ClassDefault, "|", CharDelimiter },
{ '^', ClassDefault, "^", CharDelimiter },
{ EQ, ClassDefault, "==", CharDelimiter },
{ NEQ, ClassDefault, "!=", CharDelimiter },
{ GT, ClassDefault, ">", CharDelimiter },
{ GTE, ClassDefault, ">=", CharDelimiter },
{ LT, ClassDefault, "<", CharDelimiter },
{ LTE, ClassDefault, "<=", CharDelimiter },
{ AMPAMP, ClassDefault, "&&", CharDelimiter },
{ BARBAR, ClassDefault, "||", CharDelimiter },
{ LEX_WHITE, ClassDefault, "white space", CharWhiteSpace  },
{ LEX_COMMENT, ClassComment, "comment", CharComment },
{ '.', ClassDefault, "'.'", CharDelimiter, TriggerMemberSelect },

    //always end with the 'TokenEnd' token.
    { TokenEnd,     ClassText,      "<unknown>" }
  };

  return tokenInfoTable;
};
